home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Sherlock 2.0
/
Sherlock_DevLib
/
sl_init.c
< prev
next >
Wrap
Text File
|
1996-04-06
|
10KB
|
492 lines
/*
Sherlock initialization routines.
source: sl_init.c
started: November 4, 1993.
version:
February 5, 1996.
Added support for Symantec C.
September 26, 1995.
log_open now takes only one argument.
January 7, 1994.
*/
#include <LIBlib.h>
#include <sl.h>
#include <sl2.h>
#include <LIBenv.h>
#include <LIBlog.h>
#include <LIBmem.h>
#if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
#include <mac_gui.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
/*
Globals initialized by this module...
*/
/*
The call stack.
*/
sl_snode * sl_stack = NULL; /* Dynamically allocated. */
int sl_level = 0; /* Stack pointer. */
int sl_lmax = 0; /* Max stack pointer. */
/*
The hash table.
*/
sl_node ** sl_htab = NULL;
/*
The wildcard list.
*/
sl_node * sl_wcard = NULL; /* Head of wildcard list. */
/*
The "check" name of the current macro.
*/
char * sl_cname = NULL; /* The "check" name of current macro. */
/*
The local and global disable counts.
*/
long sl_ldisable = 0; /* Local disable count. */
long sl_gdisable = 0; /* Global disable count. */
/*
Global flags.
sl_troff is TRUE initially to avoid trouble if Sherlock
macros are called before SL_INIT is called.
*/
bool sl_troff = TRUE; /* TRUE: all tracing disabled. */
bool sl_nodots = FALSE; /* TRUE: no level dots. */
bool sl_warning = TRUE; /* TRUE: warn about negative time. */
bool sl_full_trace = FALSE; /* TRUE: make STATB the same as TICKB. */
long sl_neg_count = 0; /* Number of negative times. */
int sl_node_count = 0; /* Allocated nodes. */
#if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
UnsignedWide sl_wide_time;
#endif
/*
Variables local to this file.
*/
static bool init_flag = FALSE; /* Sherlock inited flag. */
static sl_node *node_table = NULL; /* Dynamically allocated. */
static bool signon_flag = FALSE; /* TRUE: the signon message has been printed. */
/*
Function prototypes of internal routines.
*/
static int sl_prefix (char *, char *);
static void sl_set (char *, int);
/*
Enable Sherlock macros initially.
*/
void
sl_go(void)
{
if (!init_flag) {
sl_troff = FALSE;
init_flag = TRUE;
}
}
/*
SL_INIT macro--Initialize the statistics routines.
*/
void
sl_init(char * version)
{
/*
Allocate Sherlock's tables.
Nothing bad happens sl_init is called twice.
*/
if (node_table == NULL) {
node_table = lib_calloc( (size_t) SL_MAX_NODES, sizeof(sl_node));
sl_stack = lib_calloc( (size_t) SL_MAX_STACK, sizeof(sl_snode));
sl_htab = lib_calloc( (size_t) SL_MAX_HASH, sizeof(sl_node *));
if (node_table == NULL || sl_stack == NULL || sl_htab == NULL) {
sl_abort(SL_ABORT_INIT);
}
}
/* Set size of initial stack area. */
#if 0 // defined(THINK_C) // doesn't work on PowerPc
sl_min_margin = sl_margin_start = env_stackMargin();
#endif
/* 7/17/89: indicate that we are starting to initialize. */
sl_troff = FALSE;
if (strcmp(version, SL_VERSION_NAME) != 0) {
es("sl_init: Header version "); es(version);
es(" does not match run-time version: ");
es(SL_VERSION_NAME); enl();
sl_exit();
}
/*
PC only code:
Initialize the interrupt vectors. See prf.asm.
*/
#if defined(TURBOC) || defined(MICRO_SOFT)
sl_von();
DEBUG(es("Trap vectors installed.\n"));
#endif
}
/*
Return TRUE if string s1 matches string s2 with wildcards possible in
string s1.
The string s2 may start with '-', which inhibits wildcard matches.
*/
int
sl_match(register char *s1, register char *s2)
{
register char c;
/* '-' inhibits wildcard matches. */
if (*s2 == '-') {
return FALSE;
}
for (;;) {
c = *s1++;
if (c == '\0') {
return !*s2;
}
else if (c == '*') {
/* Matches zero or more characters. */
return TRUE;
}
else if (c == '?') {
/* Matches exactly one character. */
if (*s2 == '\0') {
return FALSE;
}
else {
s2++;
}
}
else if (c != *s2++) {
return FALSE;
}
}
}
/*
Allocate a new node for tracepoint s from the static node table.
If a match is found from the wildcard list, use that value for tracing.
Otherwise, set the tracing field to zero (FALSE).
*/
sl_node *
sl_new(char *s)
{
register sl_node * node, *p;
if (node_table == NULL) {
sl_abort(SL_ABORT_NEW);
}
/* Not found. Point node at a new node. */
if (sl_node_count >= SL_MAX_NODES) {
es("sl_new: trace table overflow\n");
sl_exit();
}
/* Create the new node. */
node = node_table + sl_node_count;
sl_node_count++;
node -> name = s;
node -> calls = 0;
/*
Search the wildcard list for a node which matches s.
If found. Set trace field.
*/
for (p = sl_wcard; p; p = p -> next) {
if (sl_match(p -> name, s)) {
node -> trace = (p -> trace) ? ((p -> trace) | SL_WILD_BIT) : 0;
return node;
}
}
/* No match. */
node -> trace = 0;
return node;
}
/*
SL_OFF macro.
Turn tracing off for one variable or a class of variables.
*/
void
sl_off(char *s)
{
if (strcmp(s, "sl_trace")==0) {
ecnl(); es("Disabling ALL tracing...\n");
sl_troff = TRUE;
return;
}
if (strcmp(s, "sl_dots")==0) {
ecnl(); es("Disabling level dots...\n");
sl_nodots = TRUE;
return;
}
if (strcmp(s, "sl_time")==0) {
ecnl(); es("Disabling time reporting...\n");
sl_time_flag = FALSE;
return;
}
if (strcmp(s, "sl_warning")==0) {
ecnl(); es("Disabling negative time warning...\n");
sl_warning = FALSE;
return;
}
if (!signon_flag) {
sl_signon();
}
es("Disabling trace of "); es(s); enl();
sl_cname = "TRACE_OFF";
sl_set(s, 0);
}
/*
SL_ON macro.
Turn tracing on for one variable or a class of variables.
*/
void
sl_on(char *s)
{
/* BUG FIX to V1.5 */
if (sl_troff && sl_match(s, "trace")) {
es("Revoking --trace...\n");
es("WARNING: this may generate call stack underflows.\n");
sl_troff = FALSE;
return;
}
if (strcmp(s, "sl_full_trace")==0) {
ecnl(); es("Tracing statb macros...\n");
sl_full_trace = TRUE;
return;
}
/*
++>>file_name opens file_name.
We want to sign on just *after* the ++>> arg opening the log file,
and we will assume the ++>> arg is the first arg.
*/
if (*s == '>' && *(s+1) == '>') {
/* 9/26/95: log_open now takes only one argument. */
log_open(s+2);
if (!signon_flag) {
sl_signon();
}
}
else {
if (!signon_flag) {
sl_signon();
}
es("Enabling trace of "); es(s); enl();
sl_cname = "TRACE_ON";
sl_set(s, 1);
}
}
/*
SL_PARSE macro--Parse the command list.
argcp points to the argc count.
argv contains pointers to the arguments.
on_str and off_str are the on_prefix and off_prefix respectively.
*/
void
sl_parse(argcp, argv, on_str, off_str)
int *argcp; char **argv; char *on_str; char *off_str;
{
char ** base;
char * arg;
int argc;
size_t on_len, off_len;
on_len = strlen(on_str);
off_len = strlen(off_str);
argc = *argcp;
argc--;
argv++;
base = argv;
while (argc-- > 0) {
arg = *argv++;
/* 8/8/89: Protect against over-run user error. */
if (arg == 0L) {
es("Warning: argc argument to SL_PARSE too big\n");
return;
}
if (sl_prefix(on_str, arg)) {
if (!*(arg + on_len)) {
es("Warning: lone "); es(on_str); enl();
sl_exit();
}
sl_on(arg + on_len);
/* One less argument for the program. */
(*argcp)--;
}
else if (sl_prefix(off_str, arg)) {
if (!*(arg + off_len)) {
es("Warning: lone "); es(off_str); enl();
sl_exit();
}
sl_off(arg + off_len);
/* One less argument for the program. */
(*argcp)--;
}
else {
/* Compact original argv vector. */
*base++ = arg;
}
}
/* 2/25/92 */
*base++ = NULL;
if (!signon_flag) {
sl_signon();
}
ecnl();
}
/*
Return TRUE if string p is a prefix of string s.
*/
static int
sl_prefix(char *p, char *s)
{
while (*p) {
if (*p++ != *s++) {
return FALSE;
}
}
return TRUE;
}
/*
Update the tracing status for string s and set the disable flags.
Enable tracing if flag is TRUE.
If s contains a wildcard, ALL nodes matching s have their enable
field set to flag and a new entry for s is added to the wild card list.
Otherwise, the single node (if it exists) which matches s has its
enable field set to flag.
*/
static void
sl_set(char *s, int flag)
{
sl_node * p = NULL;
/* Be very careful. */
if (sl_htab == NULL) {
return;
}
sl_check(s);
if (!sl_wild(s)) {
/* No wild card. Just set one flag. */
p = sl_find("SL_ON, SL_OFF or SL_PARSE", s);
p -> trace = flag;
return;
}
/* Search ALL hash lists. */
{
register int i;
for (i = 0; i < SL_MAX_HASH; i++) {
for (p = sl_htab [i]; p; p = p -> next) {
/* Bug fix: 4/19/89 wildcards possible only in first arg. */
if (sl_match(s, p -> name)) {
/* Set the wild bit only if p -> trace is not already on. */
if (p -> trace) {
p -> trace = flag;
}
else {
p -> trace = flag ? (SL_TRACE_BIT | SL_WILD_BIT) : 0;
}
}
}
}
}
/*
Add new element at the head of the wildcard list.
This will supercede any previous conflicting entries.
*/
p = sl_new(s);
p -> next = sl_wcard;
sl_wcard = p;
p -> trace = flag;
return;
}
/*
Sign on.
*/
void
sl_signon(void)
{
/* Sign on. */
es("Sherlock support routines: "); es(SL_VERSION_NAME); es(".\n");
signon_flag = TRUE;
}
/*
Return TRUE if string s1 contains a wildcard character, i.e., an
asterisk or a question mark.
*/
int
sl_wild(register char *s)
{
register char c;
for (;;) {
c = *s++;
if (c == '\0') {
return FALSE;
}
else if (c == '*' || c == '?') {
return TRUE;
}
}
}